package cndw.core.dispatch.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 控制器Annotation,用于类,方法<br/>
 * 只有标注此Annotation的类被认为是控制器类.<br/>
 * 控制器类里面标注此Annotation的方法识为一个Action.<br/>
 * <br/><br/>
 * 如果要在控制器中拿到本次请求的Request实例,可在控制器中做如下声明<br/>
 * <code>＠Resource Request req;</code>
 * <br/>
 * 控制器方法的返回值可以是Response,null或其它任何Object,<br/>
 * <li>1.返回值是null时,不返回数据给客户端.</li>
 * <li>2.返回值是其它Object时,默认以方法执行成功处理,封装成Response对象返回给客户端.</li>
 * <li>3.返回值是Response类型时,直接返回给客户端.</li>
 * <br/>
 * 
 * @author zuojie.x
 */
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action {
	/**
	 * 用来识别Action的标识,每个Action必须分配唯一的Id
	 * @return 业务Id
	 */
	int id() default -1;
	
	/**
	 * 默认为0L,当业务的执行时间超过{@link #timeout()}指定时间时,执行结果不返回.
	 * 
	 * @return 超时时间(毫秒), 0表示永不超时
	 */
	long timeout() default 0L;

	/**
	 * 如果需要登录验证,那么将检查{@link cndw.core.dispatch.Session#getPlayerId()}
	 * 是否为null<br/>
	 * <b>默认为true</b>
	 * 
	 * @return 是否需要登录验证
	 */
	boolean loginCheck() default true;
	
	/**
	 * 指定Action的使用用户对象<br/>
	 * <li>{@link User#Player}: 使用对象是玩家.<b>默认</b></li>
	 * <li>{@link User#System}: 使用对象是管理员,需要验证SIGN.</li>
	 * @return 用户对象
	 */
	User user() default User.Player;
	
	/**
	 * 缓存,在底层有一个映射保存着key(控制器),value(控制器执行结果 ),在使用缓存的情况下,可直接从这个映射中读取结果,而不需要再执行业务代码来提高效率.<br/>
	 * <br/>
	 * <li>{@link CacheTarget#NONE}: 不使用缓存. <b>默认</b></li>
	 * <li>{@link CacheTarget#PRIVATE}: 私有缓存,为每个用户分配私有的缓存,单个用户只会执行此Action一次,下一次请求直接返回缓存内的结果,而不再执行Action. 例:返回该用户的角色名. <b>必须登陆才能使用缓存</b></li>
	 * <li>{@link CacheTarget#PUBLIC}: 全局缓存,缓存Action的执行结果,之后任何用户请求时直接返回缓存内的结果,而不再执行Action. 例:心跳检测. <b>必须登陆才能使用缓存</b></li>
	 * @return 缓存的目标
	 */
	CacheTarget cache() default CacheTarget.NONE;
	
	/**
	 * 缓存目标
	 */
	public enum CacheTarget {
		/** 空 */
		NONE,
		/** 公共的 */
		PUBLIC,
		/** 私有的 */
		PRIVATE;
	}
	
	public enum User {
		/**
		 * 玩家权限,声明此方法提供给普通玩家使用</br>
		 * <b>Player经过{@link Action#user()}检查</b>
		 */
		Player,
		/**
		 * 管理员权限,验证SIGN提升安全性.</br>
		 * <b>{@link #System}忽略{@link Action#loginCheck()}检查</b>
		 */
		System;
	}
}
